/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package outlook;

import dto.*;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.*;
import javax.mail.internet.*;

/**
 * Mailer
 * @author Hung Cuong <nhc.hcmuns at gmail.com>
 */
public class Mailer {
    public static void sendMail(AccountDTO acc, MessageDTO msg){
        // get session
        Session session = getSession(acc);

        try {
            // convert message
            MimeMessage message = msg.toMimeMessage(session);

            // send message
            Transport transport = session.getTransport();
            transport.connect(acc.getUsername(), acc.getPassword());
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();

        } catch (Exception ex) {
            Logger.getLogger(Mailer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Receive mail
     */
    public static ArrayList<MessageDTO> getMail(AccountDTO acc) {

        ArrayList<MessageDTO> list = new ArrayList<MessageDTO>();

        Session session = getSession(acc);

        try {
            // get store
            /* pop3s, not pop3 http://java.sun.com/products/javamail/FAQ.html#gmail */
            Store store = session.getStore("pop3s");
            store.connect(acc.getInHost(), acc.getUsername(), acc.getPassword());

            // get folder
            Folder folder = store.getFolder("INBOX");
            folder.open(Folder.READ_WRITE);

            // get messages
            Message messages[] = folder.getMessages();
            MessageDTO msg = new MessageDTO();
            for(int i = 0; i < messages.length; ++i) {
                convert(messages[i], msg);
                list.add(msg);
                messages[i].setFlag(Flags.Flag.DELETED, true);
            }

            folder.close(true);
            store.close();

        } catch (Exception ex) {
            Logger.getLogger(Mailer.class.getName()).log(Level.SEVERE, null, ex);
        }

        return list;

    }

    public static void convert(MessageDTO msg, Message mail) {

    }

    public static void convert(Message mail, MessageDTO msg) throws Exception {
        msg.setFrom(mail.getFrom()[0].toString());
        msg.setTo(mail.getAllRecipients()[0].toString());
        msg.setSubject(mail.getSubject());
        msg.setBody(getText(mail)); //mail.getContent().toString());
        msg.setSentDate(mail.getSentDate().toString());
    }

    public static Session getSession(AccountDTO acc) {
        Properties props = new Properties();
        /* http://forums.sun.com/thread.jspa?threadID=617974&start=15 */
        props.setProperty("mail.smtp.starttls.enable", "true");
        props.setProperty("mail.transport.protocol", "smtp");
        props.setProperty("mail.host", acc.getOutHost());

        if(acc.getProxySet()) { // use proxy
            props.setProperty("proxySet", "true");
            props.setProperty("socksProxyHost", acc.getProxyHost());
            props.setProperty("socksProxyPort", acc.getProxyPort());
        }

        return Session.getDefaultInstance(props, null);
    }

    private static String getText(Part p) throws MessagingException, IOException {
        if (p.isMimeType("text/*")) {
            String s = (String)p.getContent();
            return s;
        }

        if (p.isMimeType("multipart/alternative")) {
            // prefer html text over plain text
            Multipart mp = (Multipart)p.getContent();
            String text = null;
            for (int i = 0; i < mp.getCount(); i++) {
                Part bp = mp.getBodyPart(i);
                if (bp.isMimeType("text/plain")) {
                    if (text == null)
                        text = getText(bp);
                    continue;
                } else if (bp.isMimeType("text/html")) {
                    String s = getText(bp);
                    if (s != null)
                        return s;
                } else {
                    return getText(bp);
                }
            }
            return text;
        } else if (p.isMimeType("multipart/*")) {
            Multipart mp = (Multipart)p.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                String s = getText(mp.getBodyPart(i));
                if (s != null)
                    return s;
            }
        }

        return null;
    }
    
}
